<!-- 表格轮播组件 -->
<template>
  <div class="list" :style="{ height: tableHeight }">
    <div class="list-header" :style="{ height: getHeight(height), lineHeight: getHeight(height) }">
      <div
        class="list-header-td"
        :style="{ width: dynamicWidth(index) }"
        v-for="(item, index) in headerList"
        >{{ item.label }}</div
      >
    </div>
    <template v-if="list.length">
      <swiper
        :slides-per-view="slides"
        :observer="true"
        :loop="loop"
        :autoplay="{
          delay: delay,
          disableOnInteraction: false
        }"
        :style="{ height: '180px' }"
        direction="vertical"
        :observe-parents="true"
      >
        <swiper-slide class="list-body-tr" v-for="i in list">
          <div class="list-body-tr" :style="{ height: getHeight(trHeight) }">
            <div
              class="list-body-td"
              :style="{ width: dynamicWidth(index - 1), lineHeight: getHeight(trHeight) }"
              v-for="index in length"
            >
              <marquee-vue :content="getContent(i, headerList[index - 1])"></marquee-vue>
            </div>
          </div>
        </swiper-slide>
      </swiper>
    </template>
    <template v-else>
      <div class="modal-empty" :style="{ marginTop: '20px' }">无数据</div>
    </template>
  </div>
</template>

<script setup lang="ts">
  import { computed, ref, onMounted } from 'vue'
  import marqueeVue from '../marquee.vue'
  import SwiperCore, { Autoplay, Swiper as SwiperType } from 'swiper'
  import { Swiper, SwiperSlide } from 'swiper/vue'
  import 'swiper/css'
  import 'swiper/css/autoplay'
  import 'swiper/css/effect-coverflow'
  import 'swiper/css/effect-creative'

  SwiperCore.use([Autoplay])
  interface HeaderMap {
    label: string
    prop: string | string[]
    width?: string | number
    splitSign?: string // 内容分隔符 当prop为数组时可定义分隔符
    formater?: (val: any) => {} // 暂不支持prop为数组的处理
    merge?: boolean
  }

  interface Prop {
    list: {
      [propName: string]: any
    }[]
    headerList: HeaderMap[]
    tableHeight?: string // 组件高度
    height?: string | number // 表头高度
    trHeight?: string | number // 行高度 所有行高度
    slides: number
    loop: boolean
    delay: number
  }

  const props = defineProps<Prop>()
  const length = ref(0)

  let dynamicWidth = computed(() => {
    return (index: number) => {
      const width = props.headerList[index]?.width || 80

      if (Number.isNaN(Number(width))) {
        return width
      } else {
        return width + 'px'
      }
    }
  })

  let getHeight = computed(() => {
    return (height?: string | number) => {
      if (height) {
        return typeof height === 'string' ? height : height + 'px'
      }
      return '36px'
    }
  })

  let getContent = computed(() => {
    return (trData: { [propName: string]: string }, map: HeaderMap) => {
      // 判断map.prop是否为数组
      let prop = map.prop
      if (typeof prop === 'string') {
        return map.formater ? map.formater(trData[prop]) : trData[prop]
      } else if (toString.call(prop) === '[object Array]') {
        let valList: string[] = []
        prop.length &&
          prop.forEach((item) => {
            valList.push(trData[item] + '')
          })
        return map.formater
          ? map.formater(valList)
          : map.splitSign
          ? valList.join(map.splitSign)
          : valList.join('/')
      } else {
        return ''
      }
    }
  })

  onMounted(() => {
    length.value = props.headerList.length
  })
</script>
<style scoped lang="scss">
  .list {
    padding-left: 40px;
    padding-right: 20px;
    .list-header {
      background: rgba($color: #04326d, $alpha: 0.53);
      border: 1px solid #0873cd;
      display: flex;
      height: 40px;
      &-td {
        font-size: 14px;
        color: #caf2f5;
        text-align: center;
      }
    }
    .list-body-tr {
      font-size: 14px;
      color: #6ea9d7;
      text-align: center;
      display: flex;
      height: 36px;
    }
  }
</style>
